const { SerialPort } = require('serialport')

// Признак производителя
const hubManufacturer =
  process.env?.HUB_MANUFACTURER || 'Joraver LTD'

const messageHubNotConnected =
  '==== Хаб противопожарной системы не присоединен'

const messageHubIsFound =
  '==== Хаб противопожарной системы обнаружен'

// Хранилище:
const store = {
  hubInfo: null, // информация порта хаба
  hub: null, // активированный инстанс, его можно read, write, close, isOpen?
  io: null, // инстанс SocketIo
}

function attachToFireLink (io) {
  store.io = io
}

function hubProbe () {
  store.hubInfo = null
  store.io.emit('setHubInfo', null)
  SerialPort.list().then(hubInfoCheck)
}

function hubInfoCheck (ports) {
  store.hubInfo = (ports || []).find(
    (port) => port.manufacturer === hubManufacturer
  ) || null

  if (!store.hubInfo) {
    console.log(new Date())
    console.log(messageHubNotConnected)
    store.io.emit('error', messageHubNotConnected)
    setTimeout(hubProbe, 1000)
  } else {
    hubOpen()
  }
}

function hubOpen() {
  if (store.hub?.isOpen) {
    store.hub.close()
  }

  console.log(new Date())
  console.log(messageHubIsFound)

  // path, manufacturer, serialNumber, pnpId, locationId, vendorId, productId
  Object.keys(store.hubInfo).forEach(
    (attr) => {
      console.log({ [attr]: store.hubInfo[attr] })
    }
  )

  const options = {
    path: store.hubInfo.path,
    baudRate: 115200,
  }

  store.hub = new SerialPort(options, hubOpenCallback)
}

function hubOpenCallback (error) {
  if (error) {
    console.log('==== OPEN HUB Error: ', error)
    setTimeout(hubProbe, 1000)
  } else {
    hubPrepare()
  }
}

function hubPrepare () {
  store.hub.on('data', (data) => {
    console.log('Прилёт:', data)
    store.io.emit('data', Array.from(data))
  })

  store.hub.on('error', (error) => {
    console.log('==== HUB ERROR', error)
    hubProbe ()
  })

  store.io.emit('setHubInfo', store.hubInfo)
}

function getHubInfo () {
  if (!store.hubInfo) {
    hubProbe()
  } else {
    store.io.emit('setHubInfo', store.hubInfo)
  }
}

function sendData (numbers) {
  // if (!store?.hubInfo) {
  if (!store?.hub?.isOpen) {
      hubProbe()
  } else {
    store.hub.write(Buffer.from(numbers))
  }
}

const fireLink = {
  sendData,
  getHubInfo,
  attachToFireLink,
}

module.exports = fireLink
